﻿#ifndef _XSTRINGMAP_H_
#define _XSTRINGMAP_H_
#include<vector>
using namespace std;
template<typename T>
class XStringMap
{
public:
	XStringMap() {};
	~XStringMap() {};
public:
	void insert(const T& key, const T& val);
	void erase(const T& key);
public:
	bool contains(const T& key)const;
	T value(const T& key) const;
	//连接成一个字符串
	T join(const T& prefix, const T& separator, const T& suffix)const;

	bool isEmpty()const;
	size_t size()const;
	vector<pair<T, T>>& data();
	void clear();
	auto begin();
	auto end();
	auto begin()const;
	auto end()const;
public:
	T& operator[](const T& key);
	T operator[](const T& key)const;
private:
	//QHash<T, T> m_data;
	//QHash<T, quint64> m_Index;
	vector<pair<T, T>> m_data;

};


template<typename T>
inline bool XStringMap<T>::contains(const T& key)const
{
	auto data = find_if(m_data.begin(), m_data.end(), [&](const pair<T, T>& data) {return data.first == key; });
	if (data == m_data.end())
		return false;
	return true;
}

template<typename T>
inline T XStringMap<T>::value(const T& key) const
{
	for (const pair<T, T>&pair:m_data)
	{
		if (pair.first == key)
			return pair.second;
	}
	return T();
}
template<typename T>
inline void XStringMap<T>::insert(const T& name, const T& val)
{
	auto data = find_if(m_data.begin(), m_data.end(), [=](pair<T, T>& data) {return data.first == name; });
	if (data == m_data.end())
		m_data.push_back(pair<T, T>(name, val));
	else
		data->second = val;
}

template<typename T>
inline void XStringMap<T>::erase(const T& name)
{
	auto data = find_if(m_data.begin(), m_data.end(), [=](pair<T, T>& data) {return data.first == name; });
	if (data != m_data.end())
		m_data.erase(data);
}

template<typename T>
inline T XStringMap<T>::join(const T& prefix, const T& separator, const T& suffix)const
{
	T str;
	for (auto& data : m_data)
	{
		str += prefix;
		str += data.first;
		str += separator;
		str += data.second;
		str += suffix;
	}
	return str;
}

template<typename T>
inline T& XStringMap<T>::operator[](const T& key)
{
	auto data = find_if(m_data.begin(), m_data.end(), [=](pair<T, T>& data) {return data.first == key; });
	if (data == m_data.end())
	{
		m_data.push_back(pair<T, T>(key, ""));
		return m_data.back().second;
	}
	else
	{
		return data->second;
	}
}
template<typename T>
inline T XStringMap<T>::operator[](const T& key) const
{
	auto data = find_if(m_data.begin(), m_data.end(), [=](const pair<T, T>& data) {return data.first == key; });
	if (data == m_data.end())
		return T();
	else
		return data->second;
}
template<typename T>
inline bool XStringMap<T>::isEmpty() const
{
	return m_data.empty();
}
template<typename T>
inline size_t XStringMap<T>::size() const
{
	return m_data.size();
}
template<typename T>
inline vector<pair<T, T>>& XStringMap<T>::data()
{
	return m_data;
}
template<typename T>
inline void XStringMap<T>::clear()
{
	m_data.clear();
}
template<typename T>
inline auto XStringMap<T>::begin()
{
	return m_data.begin();
}
template<typename T>
inline auto XStringMap<T>::end()
{
	return m_data.end();
}
template<typename T>
inline auto XStringMap<T>::begin() const
{
	return m_data.begin();
}
template<typename T>
inline auto XStringMap<T>::end() const
{
	return m_data.end();
}
#endif // !_FINDSTR_H_